/**
 * JimBot - Java IM Bot
 * Copyright (C) 2006-2009 JimBot project
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package ru.jimbot.modules.anek;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Properties;

import ru.jimbot.modules.AbstractProps;
import ru.jimbot.table.UserPreference;
import ru.jimbot.util.Log;

/**
 *
 * @author Prolubnikov Dmitry
 */
public class AnekProps implements AbstractProps {
    public static HashMap<String,AnekProps> props = new HashMap<String,AnekProps>();
    public String PROPS_FILE = "";
    private String PROPS_FOLDER = "";
    public String ENCODING = "windows-1251";
    public Properties appProps;
    public Properties langProps;
    public boolean isLoaded = false;
    
    /** Creates a new instance of AnekProps */
    public AnekProps() {
    }
    
    public static AnekProps getInstance(String name){
    	if(props.containsKey(name))
    		return props.get(name);
    	else {
    		AnekProps p = new AnekProps();
    		p.PROPS_FILE = "./services/"+name+"/"+name+".xml";
    		p.PROPS_FOLDER = "./services/"+name;
    		p.setDefault();
    		p.load();
    		props.put(name, p);
    		return p;
    	}
    }
    
    public void setDefault() {
        appProps = new Properties();
        setIntProperty("conn.accCount",1);
        setIntProperty("conn.type0", 1);
        setStringProperty("conn.acc0","111");
        setStringProperty("conn.pass0","Password");
        setStringProperty("icq.status","0"/*Icq.STATUS_ONLINE*/);
        setStringProperty("icq.xstatus","0");
        
        setStringProperty("icq.client", "8" );
        setBooleanProperty("web.aware.on.off", true);
        setStringProperty("icq.pstatus", "1");
        
//        setIntProperty("icq.statusFlag",0);
        
        setIntProperty("auto_status.time", 5 );
        setBooleanProperty("auto_status.on.off", false);
        
        setIntProperty("bot.pauseIn",3000); //Пауза входящих сообщений
        setIntProperty("bot.pauseOut",500); //Пауза исходящих сообщений
        setIntProperty("bot.msgOutLimit",20); //Ограничение очереди исходящих сообщений
        setIntProperty("bot.pauseRestart",11*60*1000); //Пауза перед запуском упавшего коннекта
        setStringProperty("bot.adminUIN","111111;222222");
        setIntProperty("icq.AUTORETRY_COUNT",5);
        setStringProperty("icq.STATUS_MESSAGE1","");
        setStringProperty("icq.STATUS_MESSAGE2","");
        setBooleanProperty("icq.roster", false);
        setBooleanProperty("bot.useAds",false);
        setIntProperty("bot.adsRate",3);
        setBooleanProperty("main.StartBot",false);
        setIntProperty("chat.MaxOutMsgSize",500);
        setIntProperty("chat.MaxOutMsgCount",5); 
        
        setStringProperty("vk.online", "off");
    }

    private String[][] icqStatus = {{"0", "В сети"}, {"268435456", "Не в сети"}, {"10", "Занят"},
    {"4", "Недоступен"}, {"512", "Невидим для всех"}, {"256", "Невидим"}, {"2", "Не беспокоить"},
    {"32", "Готов поболтать"}, {"1", "Отошёл"}, {"8193", "Кушаю"}, {"24576", "Работа"}, {"20480", "Дома"},
    {"16384", "Депрессия"}, {"12288", "Злой"}};

    private String[][] icqXstatus = {{"0", "Нет"}, {"1", "Злой"}, {"2", "Купаюсь"}, {"3", "Устал"},
    {"4", "Вечеринка"}, {"5", "Пиво"}, {"6", "Думаю"}, {"7", "Кушаю"}, {"8", "ТВ"}, {"9", "Друзья"},
    {"10", "Кофе"}, {"11", "Слушаю музыку"}, {"12", "Дела"}, {"13", "Кино"}, {"14", "Весело"},
    {"15", "Телефон"}, {"16", "Играю"}, {"17", "Учусь"}, {"18", "Магазины"}, {"19", "Болею"}, {"20", "Сплю"},
    {"21", "Отрываюсь"}, {"22", "Интернет"}, {"23", "Работаю"}, {"24", "Печатаю"}, {"25", "Пикник"},
    {"26", "Готовлю"}, {"27", "Курю"}, {"28", "Релакс"}, {"29", "Туалет"}, {"30", "Вопрос"},
    {"31", "Дорога"}, {"32", "Любовь"}, {"33", "Поиск"}, {"34", "Дневник"}, {"35", "Секс"}, 
    {"36", "RuLove"}, {"37", "Курю"}};
    
    private String[][] icqPStatus = { { "1", "Видимый для всех" }, { "2", "Невидимый для всех" },
    { "3", "Видимый для списка видящих" }, { "4", "Невидимый для списка невидящих" },
    { "5", "Видимый для списка контактов" } };

    private String[][] icqClient = {{"0", "Unknown"}, {"1", "QIP PDA Symbian"},
    {"2", "QIP PDA Windows"}, {"3", "Licq"}, {"4", "mChat"}, {"5", "mIcq"}, {"6", "Qutim"}, {"7", "Bayan ICQ"},
    {"8", "Kopete"}, {"9", "PalmJicq"}, {"10", "VmICQ"}, {"11", "Yaap"}, {"12", "D[i]Chat"}, {"13", "MipClient"},
    {"14", "JappSergo"}, {"15", "QIP Mobile iPhone"}, {"16", "Jit"}, {"17", "Miranda"}, {"18", "Climm"}, {"19", "Anastasia"}, 
    {"20", "Inlux Messenger"}, {"21", "JIMM"}, {"22", "LocID"}, {"23", "Trillian"}, {"24", "Smaper"}, {"25", "PIGEON"},
    {"26", "IM+"},{"27", "QIP 2005 "}};
    
    private String[][] vk_online = {{"off", "Выкл"}, {"pc", "ПК"},
    {"mobile", "Мобильный"}};
    
    public UserPreference[] getUserPreference(){
        UserPreference[] p = {
            new UserPreference(UserPreference.CATEGORY_TYPE,"main", "Основные настройки"),
            new UserPreference(UserPreference.BOOLEAN_TYPE,"main.StartBot","Запускать анекдотный бот",getBooleanProperty("main.StartBot"),true),
            new UserPreference(UserPreference.CATEGORY_TYPE,"anek", "Настройки анекдотного бота"),
            new UserPreference(UserPreference.INTEGER_TYPE,"icq.status","ICQ статус",getStringProperty("icq.status"),true),
            new UserPreference(UserPreference.INTEGER_TYPE,"icq.xstatus","x-статус (0-34)",getStringProperty("icq.xstatus"),true),
            //new UserPreference(UserPreference.STRING_TYPE,"icq.STATUS_MESSAGE1","Сообщение x-статуса 1",getStringProperty("icq.STATUS_MESSAGE1"),true),
            new UserPreference(UserPreference.STRING_TYPE,"icq.STATUS_MESSAGE2","Текст статуса",getStringProperty("icq.STATUS_MESSAGE2"),true),
//            new UserPreference(UserPreference.INTEGER_TYPE,"icq.statusFlag","Дополнительный статус",getIntProperty("icq.statusFlag")),
            new UserPreference(UserPreference.BOOLEAN_TYPE,"auto_status.on.off","Включить/Выключить авто смену x-status`ов",getBooleanProperty("auto_status.on.off"), true),
            new UserPreference(UserPreference.INTEGER_TYPE,"auto_status.time","Интервал смены x-status`ов",getIntProperty("auto_status.time"), true),
            new UserPreference(UserPreference.INTEGER_TYPE,"icq.AUTORETRY_COUNT","Число переподключений движка при обрыве",getIntProperty("icq.AUTORETRY_COUNT"),true),
            new UserPreference(UserPreference.BOOLEAN_TYPE,"icq.roster","Вкл/Выкл работу с КЛ",getBooleanProperty("icq.roster"),true),
            new UserPreference(UserPreference.BOOLEAN_TYPE,"ball.of.joy.on.off","Включить шарик радости",getBooleanProperty("ball.of.joy.on.off"),true),
            new UserPreference(UserPreference.BOOLEAN_TYPE,"web.aware.on.off","Индексировать номера в поиске(Web Aware)",getBooleanProperty("web.aware.on.off"),true),
            new UserPreference(UserPreference.SELECT_TYPE,"icq.client","ID icq клиента",getStringProperty("icq.client"),icqClient,true),
            new UserPreference(UserPreference.SELECT_TYPE, "icq.pstatus", "Приватный статус", getStringProperty("icq.pstatus"), icqPStatus,true),
            new UserPreference(UserPreference.SELECT_TYPE, "vk.online", "Онлайн статус ВКонтакте", getStringProperty("vk.online"), vk_online,true),
//            new UserPreference(UserPreference.STRING_TYPE,"icq.STATUS_MESSAGE","Сообщение статуса",getStringProperty("icq.STATUS_MESSAGE")),
            new UserPreference(UserPreference.INTEGER_TYPE,"bot.pauseIn","Пауза для входящих сообщений",getIntProperty("bot.pauseIn"),true),
            new UserPreference(UserPreference.INTEGER_TYPE,"bot.pauseOut","Пауза для исходящих сообщений",getIntProperty("bot.pauseOut"),true),
            new UserPreference(UserPreference.INTEGER_TYPE,"bot.msgOutLimit","Ограничение очереди исходящих",getIntProperty("bot.msgOutLimit"),true),
            new UserPreference(UserPreference.INTEGER_TYPE,"chat.MaxOutMsgSize","Максимальный размер одного исходящего сообщения",getIntProperty("chat.MaxOutMsgSize"),true),
            new UserPreference(UserPreference.INTEGER_TYPE,"chat.MaxOutMsgCount","Максимальное число частей исходящего сообщения",getIntProperty("chat.MaxOutMsgCount"),true),
            new UserPreference(UserPreference.INTEGER_TYPE,"bot.pauseRestart","Пауза перед перезапуском коннекта",getIntProperty("bot.pauseRestart"),true),
            new UserPreference(UserPreference.STRING_TYPE,"bot.adminUIN","Админские UIN",getStringProperty("bot.adminUIN"),true),
            new UserPreference(UserPreference.BOOLEAN_TYPE,"bot.useAds","Использовать рекламу в боте",getBooleanProperty("bot.useAds"),true),
            new UserPreference(UserPreference.INTEGER_TYPE,"bot.adsRate","Частота рекламы",getIntProperty("bot.adsRate"),true)
        };
        return p;
    }
    
    public UserPreference[] getAccPreference(){
        UserPreference[] p = new UserPreference[accCount()*3+1];
        p[0] = new UserPreference(UserPreference.CATEGORY_TYPE,"conn", "Настройки UINов для подключения");
        for(int i=0;i<accCount();i++){
            p[i*3+1] = new UserPreference(UserPreference.INTEGER_TYPE,"conn.type" + i,"Type" + i,getProperty("conn.uin" + i,""), true);
            p[i*3+2] = new UserPreference(UserPreference.STRING_TYPE,"conn.acc" + i,"Account" + i,getProperty("conn.uin" + i,""),true);
            p[i*3+3] = new UserPreference(UserPreference.PASS_TYPE,"conn.pass" + i,"Password" + i,getProperty("conn.pass" + i, ""),true);
        }
        return p;
    }

    public boolean isAutoStart(){
    	return getBooleanProperty("main.StartBot");
    }
    
    public int accCount(){
        return getIntProperty("conn.accCount");
    }
    
    public int getType(int i) {
        return getIntProperty("conn.type"+i);
    }
    
    public String getAcc(int i){
        return getStringProperty("conn.acc"+i);
    }
    
    public String getPass(int i){
        return getStringProperty("conn.pass"+i);
    }    
    
    /**
     * Изменение уина
     * @param i
     * @param type
     * @param acc
     * @param pass
     */
    public void setAcc(int i, int type, String acc, String pass){
        setIntProperty("conn.type"+i, type);
    	setStringProperty("conn.acc"+i, acc);
    	setStringProperty("conn.pass"+i, pass);
    }
    
    /**
     * Добавление нового уина в настройки
     * @param type - тип
     * @param acc - account
     * @param pass - пароль
     * @return - порядковый номер нового уина
     */
    public int addAcc(int type, String acc, String pass){
    	int c = accCount();
    	setIntProperty("conn.accCount", c+1);
        setIntProperty("conn.type"+c, type);
    	setStringProperty("conn.acc"+c, acc);
    	setStringProperty("conn.pass"+c, pass);
    	return c;
    }
    
    /**
     * Удаление уина из настроек
     * @param c
     */
    public void delAcc(int c) {
    	// Сдвигаем элементы после удаленного
    	for(int i=0; i<(accCount()-1); i++){
    		if(i>=c){
                        setIntProperty("conn.type"+i, getType(i+1));
    			setStringProperty("conn.acc"+i, getAcc(i+1));
    			setStringProperty("conn.pass"+i, getPass(i+1));
    		}
    	}
    	//Удаляем самый последний элемент
        appProps.remove("conn.type"+(accCount()-1));
    	appProps.remove("conn.acc"+(accCount()-1));
    	appProps.remove("conn.pass"+(accCount()-1));
    	setIntProperty("conn.accCount", accCount()-1);
    }
    
    public boolean testAdmin(String uin) {
        if(uin.equals("0")) return true; //Выртуальный админ
        String s = getStringProperty("bot.adminUIN");
        if(s.equals("")) return true;
        String[] ss = s.split(";");
        try{
            for(int i=0;i<ss.length;i++){
                if(ss[i].equalsIgnoreCase(uin)) return true;
            }
        } catch(Exception ex){
            ex.printStackTrace();
        }
        return false;
    }

    public String[] getAdmins(){
    	return getStringProperty("bot.adminUIN").split(";");
    }

    public final void load() {
        File file = new File(PROPS_FILE);
        setDefault();
        try {
            FileInputStream fi = new FileInputStream(file);
//            appProps.load(fi);
            appProps.loadFromXML(fi);
            fi.close();
            Log.info("Load preferences ok");
        } catch (Exception ex) {
            ex.printStackTrace();
            Log.error("Error opening preferences: ");
        }
    }
    
    public final void save() {
        File file = new File(PROPS_FILE);
        File dir = new File(this.PROPS_FOLDER);
        try {
        	if(!dir.exists())
        		dir.mkdirs();
            FileOutputStream fo = new FileOutputStream(file);
//            appProps.store(fo,"jImBot properties");
            appProps.storeToXML(fo, "jImBot properties");
            fo.close();
            Log.info("Save preferences ok");
        } catch (Exception ex) {
            ex.printStackTrace();
            Log.error("Error saving preferences: ");
        }
    }
    
        public String loadText(String fname) {
        String s = "";
        try {
            BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(fname),"UTF-8"));
            while (r.ready()) {
                s += r.readLine() + "\n";
            }
            r.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return s;
    }

    public void registerProperties(Properties _appProps) {
        appProps = _appProps;
    }
    
    public String getProperty(String key) {
        return appProps.getProperty(key);
    }
    
    public String getStringProperty(String key) {
        return appProps.getProperty(key);
    }
    
    public String getProperty(String key, String def) {
        return appProps.getProperty(key,def);
    }
    
    public void setProperty(String key, String val) {
        appProps.setProperty(key,val);
    }
    
    public void setStringProperty(String key, String val) {
        appProps.setProperty(key,val);
    }
    
    public void setIntProperty(String key, int val) {
        appProps.setProperty(key,Integer.toString(val));
    }
    
    public void setBooleanProperty(String key, boolean val) {
        appProps.setProperty(key, val ? "true":"false");
    }
    
    public int getIntProperty(String key) {
        return Integer.parseInt(appProps.getProperty(key));
    }
    
    public boolean getBooleanProperty(String key) {
        return Boolean.valueOf(appProps.getProperty(key)).booleanValue();
    }

	public Properties getProps() {
		return appProps;
	}    
        
    @Override
    public boolean isRoster() {
        return getBooleanProperty("icq.roster");
    }
}
